﻿

#ifndef IM_Epoll_h__
#define IM_Epoll_h__


#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>

#define _DEBUG
#include "Log.h"


class IM_Epoll
{
public:
	IM_Epoll() 
	{
		m_epoll_fd = epoll_create(1024);
	}
	~IM_Epoll() { close(m_epoll_fd); }

	struct EpollEvent {
		void * s;
		bool read;
		bool write;
		bool error;
	};

	inline bool add_socket(int sock, void * ud)
	{
		epoll_event ev;
		ev.events = EPOLLIN;
		ev.data.ptr = ud;
		if (epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, sock, &ev) == -1)
		{
			return false;
		}
		DEBUG("在epoll 添加一个 socket %d , mmaddr :%p\n",sock,ud);
		return true;
	}

	inline void del_socket(int sock)
	{
		epoll_ctl(m_epoll_fd, EPOLL_CTL_DEL, sock, nullptr);
	}

	inline void set_write_socket(int sock, void *ud, bool enable)
	{
		epoll_event ev;
		ev.events = EPOLLIN | (enable ? EPOLLOUT : 0);
		ev.data.ptr = ud;
		epoll_ctl(m_epoll_fd, EPOLL_CTL_MOD, sock, &ev);
	}

	inline int wait(EpollEvent * e, int max)
	{
		epoll_event ev[max];
		int n = epoll_wait(m_epoll_fd, ev, max,-1);

		DEBUG("wait : n= %d\n", n);
		for (int i = 0; i < n; i++)
		{
			DEBUG("查询到socket event\n");
			DEBUG("mmaddr %p\n",ev[i].data.ptr);
			e[i].s = ev[i].data.ptr;
			unsigned int flag = ev[i].events;
			e[i].write = (flag&EPOLLOUT) != 0;
			e[i].read = (flag&(EPOLLIN | EPOLLHUP)) != 0;
			e[i].error = (flag&EPOLLERR) != 0;
		}

		return n;
	}

private:
	int   m_epoll_fd;
};


#endif // IM_Epoll_h__